From d948120eed5d3922d208a6da374a92787744f013 Mon Sep 17 00:00:00 2001 From: Luca Bruno Date: Thu, 3 Dec 2015 00:12:29 +0100 Subject: [PATCH] vendor: add pack/unpack helpers --- debian/cargo-vendor-pack.py | 144 ++++++++++++++++++++++++++++++++++ debian/cargo-vendor-unpack.py | 32 ++++++++ 2 files changed, 176 insertions(+) create mode 100755 debian/cargo-vendor-pack.py create mode 100755 debian/cargo-vendor-unpack.py diff --git a/debian/cargo-vendor-pack.py b/debian/cargo-vendor-pack.py new file mode 100755 index 000000000..7ae9ef1e8 --- /dev/null +++ b/debian/cargo-vendor-pack.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python + +# Copyright: 2015 The Debian Project +# License: MIT-License or Apache-2.0 +# +# Helper to generate a crate registry from local unpacked crates +# TODO: very bad code. It should be rewritten in perl and converted into dh_cargo + +import json +import os +import tarfile +import string +import pytoml +from dulwich.repo import Repo +import hashlib +from collections import OrderedDict + + +# TODO: hackish, at best. features need to be properly parsed +def parse_deps(toml): + deps=[] + if 'dependencies' not in toml: + return deps + d = toml['dependencies'] + if 'target' in toml: + t = toml['target'] + if 'x86_64-unknown-linux-gnu' in t: + t = t['x86_64-unknown-linux-gnu'] + if 'dependencies' in t: + d.update(t['dependencies']) + for k, v in d.iteritems(): + opt = False + defa = True + if isinstance(v, dict): + opt = v.get('optional', opt) + v = '*' + i = { + "default_features": defa, + "features": [], + "kind": "normal", + "name": k, + "optional": opt, + "req": v, + "target": None + } + deps.append(i) + if 'build-dependencies' not in toml: + return deps + d = toml['build-dependencies'] + for k, v in d.iteritems(): + opt = False + defa = True + if isinstance(v, dict): + opt = v.get('optional', opt) + v = '*' + i = { + "default_features": defa, + "features": [], + "kind": "build", + "name": k, + "optional": opt, + "req": v, + "target": None + } + deps.append(i) + return deps + +def main(): + curdir = os.getcwd() + depsdir = os.path.join(curdir, "deps") + vendordir = os.path.join(curdir, "vendor") + cachedir = os.path.join(vendordir, "cache") + indexdir = os.path.join(vendordir, "index") + cargocfgdir = os.path.join(curdir, ".cargo") + for d in [cachedir, indexdir]: + if not os.path.exists(d): + os.makedirs(d) + + indexdict = OrderedDict() + for crate in os.listdir(depsdir): + if os.path.isdir(os.path.join(depsdir, crate)) and not crate.startswith('.'): + (name, ver) = string.rsplit(crate, '-', 1) + print("Found %s ver. %s (at %s)" % (name, ver, os.path.join(depsdir, crate))) + destdir=(os.path.join(cachedir, name, ver)) + os.makedirs(destdir) + tarcrate = os.path.join(destdir, "download") + tar = tarfile.open(tarcrate, "w:gz") + tar.add(os.path.join(depsdir, crate), arcname=crate) + tar.close() + + manif = None + with open(os.path.join(depsdir,crate,'Cargo.toml'), 'rb') as f: + manif = pytoml.load(f) + + nestdir = None + if len(name) >= 4: + nestdir = os.path.join(indexdir, name[0:2], name[2:4]) + else: + nestdir = os.path.join(indexdir, '3', name[0]) + + cksum = hashlib.sha256(open(tarcrate, 'rb').read()).hexdigest() + indexdict[name] = OrderedDict([ + ('name', name), + ('vers', ver), + ('deps', parse_deps(manif)), + ('features', manif.get('features',{})), + ('cksum', cksum), + ('yanked', False) + ]) + if not os.path.exists(nestdir): + os.makedirs(nestdir) + with open(os.path.join(nestdir, name), 'a') as outfile: + json.dump(indexdict[name], outfile, sort_keys=False) + outfile.write('\n') + + + configjson = { + 'api': '', + 'dl': "file://{0}".format(cachedir) + } + with open(os.path.join(indexdir, 'config.json'), 'w') as outfile: + json.dump(configjson, outfile) + + p = [] + for dirpath, _, paths in os.walk(indexdir): + for f in paths: + p.append(os.path.relpath(os.path.join(dirpath,f), indexdir)) + + repo=Repo.init(indexdir) + for f in paths: + repo.stage(p) + repo.do_commit(b"Fake commit", committer=b"Cargo debhelper ") + + cfg="""[registry] +index = "file://{0}" +""" + if not os.path.exists(cargocfgdir): + os.makedirs(cargocfgdir) + + with open(os.path.join(cargocfgdir, "config"), "w") as cfgfile: + cfgfile.write(cfg.format(indexdir)) + +if __name__ == "__main__": + main() diff --git a/debian/cargo-vendor-unpack.py b/debian/cargo-vendor-unpack.py new file mode 100755 index 000000000..0e9f0b9c0 --- /dev/null +++ b/debian/cargo-vendor-unpack.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +# Copyright: 2015 The Debian Project +# License: MIT-License or Apache-2.0 +# +# Helper to unpack a local crate registry to original sources +# TODO: rewrite to perl, maybe? + +import os +import tarfile + +def main(): + curdir = os.getcwd() + depsdir = os.path.join(curdir, "deps") + vendordir = os.path.join(curdir, "vendor") + cachedir = os.path.join(vendordir, "cache") + if not os.path.exists(depsdir): + os.makedirs(depsdir) + + for _, names, _ in os.walk(top=cachedir): + for cratename in names: + for _, vers, _ in os.walk(top=os.path.join(cachedir, cratename)): + for cratever in vers: + crate = os.path.join(cachedir, cratename, cratever, "download") + tar = tarfile.open(crate) + tar.extractall(path=depsdir) + print("Unpacking crate deps %s" % crate) + tar.close() + + +if __name__ == "__main__": + main() -- 2.30.2